package com.scale.service.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.user.dto.UserProfileUpdateDTO;
import com.example.user.dto.PasswordUpdateDTO;
import com.example.user.entity.Users;
import com.example.user.entity.UserLoginHistory;
import com.example.conversation.entity.Conversations;
import com.example.user.vo.UserProfileVO;
import com.scale.service.user.mapper.UsersMapper;
import com.scale.service.user.mapper.UserLoginHistoryMapper;
import com.scale.service.conversation.mapper.ConversationsMapper;
import com.scale.service.user.service.UserProfileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 用户个人资料服务实现类
 * @author crp
 * @since 2025-09-28
 */
@Slf4j
@Service
public class UserProfileServiceImpl implements UserProfileService {

    @Autowired
    private UsersMapper usersMapper;
    
    @Autowired
    private UserLoginHistoryMapper loginHistoryMapper;
    
    @Autowired
    private ConversationsMapper conversationsMapper;
    
    // 使用Spring Security BCrypt加密
    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    
    @Value("${user.avatar.storage.path:D:/programme/javaEE/scale/data/avatar/}")
    private String avatarStoragePath;
    
    @Value("${user.avatar.base-url:http://localhost:8080/avatar}")
    private String avatarBaseUrl;

    @Override
    public UserProfileVO getUserProfile(Long userId) {
        // 获取用户基本信息
        Users user = usersMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        UserProfileVO profile = new UserProfileVO();
        BeanUtils.copyProperties(user, profile);
        
        // 手机号脱敏处理
        if (user.getPhone() != null && user.getPhone().length() >= 11) {
            String phone = user.getPhone();
            profile.setPhone(phone.substring(0, 3) + "****" + phone.substring(7));
        }
        
        // 获取统计信息
        try {
            // 登录次数统计
            QueryWrapper<UserLoginHistory> loginCountQuery = new QueryWrapper<>();
            loginCountQuery.eq("user_id", userId);
            Integer loginCountInt = loginHistoryMapper.selectCount(loginCountQuery);
            profile.setLoginCount(loginCountInt != null ? loginCountInt.longValue() : 0L);
            
            // 对话总数统计  
            QueryWrapper<Conversations> conversationCountQuery = new QueryWrapper<>();
            conversationCountQuery.eq("user_id", userId);
            Integer totalConversationsInt = conversationsMapper.selectCount(conversationCountQuery);
            profile.setTotalConversations(totalConversationsInt != null ? totalConversationsInt.longValue() : 0L);
            
        } catch (Exception e) {
            log.warn("获取用户统计信息失败: {}", e.getMessage());
            profile.setLoginCount(0L);
            profile.setTotalConversations(0L);
        }
        
        return profile;
    }

    @Override
    public void updateUserProfile(Long userId, UserProfileUpdateDTO updateDTO) {
        // 检查用户是否存在
        Users existingUser = usersMapper.selectById(userId);
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查用户名唯一性
        if (!existingUser.getUsername().equals(updateDTO.getUsername())) {
            QueryWrapper<Users> usernameQuery = new QueryWrapper<>();
            usernameQuery.eq("username", updateDTO.getUsername())
                        .ne("id", userId);
            if (usersMapper.selectCount(usernameQuery) > 0) {
                throw new RuntimeException("用户名已存在");
            }
        }
        
        // 检查邮箱唯一性
        if (updateDTO.getEmail() != null && !updateDTO.getEmail().equals(existingUser.getEmail())) {
            QueryWrapper<Users> emailQuery = new QueryWrapper<>();
            emailQuery.eq("email", updateDTO.getEmail())
                     .ne("id", userId);
            if (usersMapper.selectCount(emailQuery) > 0) {
                throw new RuntimeException("邮箱已被使用");
            }
        }
        
        // 更新用户信息
        Users updateUser = new Users();
        updateUser.setId(userId);
        BeanUtils.copyProperties(updateDTO, updateUser);
        updateUser.setUpdatedAt(LocalDateTime.now());
        
        int result = usersMapper.updateById(updateUser);
        if (result == 0) {
            throw new RuntimeException("更新用户信息失败");
        }
        
        log.info("用户资料更新成功: userId={}", userId);
    }

    @Override
    public String uploadAvatar(Long userId, MultipartFile avatarFile) {
        try {
            log.info("开始上传头像: userId={}, originalFileName={}, fileSize={}", 
                    userId, avatarFile.getOriginalFilename(), avatarFile.getSize());
            
            // 生成文件名
            String originalFilename = avatarFile.getOriginalFilename();
            String fileExtension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
            String fileName = String.format("user_%d_%s%s", userId, timestamp, fileExtension);
            
            // 确保存储目录存在 - 使用绝对路径
            Path storageDir = Paths.get(avatarStoragePath).toAbsolutePath();
            log.info("头像存储目录: {}", storageDir.toString());
            
            if (!Files.exists(storageDir)) {
                log.info("创建头像存储目录: {}", storageDir.toString());
                try {
                    Files.createDirectories(storageDir);
                    log.info("头像存储目录创建成功");
                } catch (IOException e) {
                    log.error("创建头像存储目录失败: {}", storageDir.toString(), e);
                    throw new RuntimeException("创建头像存储目录失败: " + e.getMessage());
                }
            }
            
            // 保存文件
            Path filePath = storageDir.resolve(fileName);
            log.info("保存头像文件到: {}", filePath.toString());
            
            try {
                avatarFile.transferTo(filePath.toFile());
                log.info("头像文件保存成功: {}", filePath.toString());
            } catch (IOException e) {
                log.error("头像文件保存失败: {}", filePath.toString(), e);
                throw new RuntimeException("头像文件保存失败: " + e.getMessage());
            }
            
            // 生成访问URL
            String avatarUrl = avatarBaseUrl + "/" + fileName;
            
            // 更新用户头像URL
            Users updateUser = new Users();
            updateUser.setId(userId);
            updateUser.setAvatarUrl(avatarUrl);
            updateUser.setUpdatedAt(LocalDateTime.now());
            
            int result = usersMapper.updateById(updateUser);
            if (result == 0) {
                throw new RuntimeException("更新用户头像失败");
            }
            
            log.info("用户头像上传成功: userId={}, avatarUrl={}, filePath={}", userId, avatarUrl, filePath.toString());
            return avatarUrl;
            
        } catch (Exception e) {
            log.error("头像上传失败: userId={}", userId, e);
            throw new RuntimeException("头像上传失败: " + e.getMessage());
        }
    }

    @Override
    public void updatePassword(Long userId, PasswordUpdateDTO passwordDTO) {
        // 获取当前用户信息
        Users user = usersMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证原密码
        if (!passwordEncoder.matches(passwordDTO.getOldPassword(), user.getPassword())) {
            throw new RuntimeException("原密码不正确");
        }
        
        // 加密新密码
        String newPasswordHash = passwordEncoder.encode(passwordDTO.getNewPassword());
        
        // 更新密码
        Users updateUser = new Users();
        updateUser.setId(userId);
        updateUser.setPassword(newPasswordHash);
        updateUser.setUpdatedAt(LocalDateTime.now());
        
        int result = usersMapper.updateById(updateUser);
        if (result == 0) {
            throw new RuntimeException("密码更新失败");
        }
        
        log.info("用户密码修改成功: userId={}", userId);
    }
}
